package li.kaeppe.travel.tracker.domain;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name="WAYPOINT",
		uniqueConstraints = {@UniqueConstraint(columnNames={"longitude", "latitude", "WAYPOINT_DATE", "trip_id"})}
)
@SequenceGenerator(name="SEQ_WAYPOINT", sequenceName="WAYPOINT_SEQUENCE")
public class WayPoint implements Serializable {
	
	/* **************************************************** */
	/*                      CONSTANTS                       */
	/* **************************************************** */
	
	private static final long serialVersionUID = -918716739729287744L;
	
	public static final Integer LEVEL_LOW = 1000;
	
	public static final Integer LEVEL_MEDIUM = 100;;
	
	public static final Integer LEVEL_HIGH = 10;
	
	public static final Integer LEVEL_ALL = 1;
	
	/* **************************************************** */
	/*                     MEMBER FIELDS                    */
	/* **************************************************** */

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO, generator="SEQ_WAYPOINT")
	private long id;
	
	@Column(precision=12, scale=6)
	private BigDecimal longitude;
	
	@Column(precision=12, scale=6)
	private BigDecimal latitude;
	
	@Column(name="WAYPOINT_DATE", nullable=true)
	private Date date;
	
	@Column(nullable=true, precision=12, scale=6)
	private BigDecimal elevation;
	
	@ManyToOne(cascade= {CascadeType.ALL})
	private Trip trip;
	
	@Column(name="WAYPOINT_LEVEL", nullable=true)
	private int level = 0;
	
	/* **************************************************** */
	/*                      CONSTRUCTOR                     */
	/* **************************************************** */

	public WayPoint() {}
	
	public WayPoint(BigDecimal longitude, BigDecimal latitude, Date date) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.date = date;
	}
	
	public WayPoint(long id, BigDecimal longitude, BigDecimal latitude, Date date) {
		this(longitude, latitude, date);
		this.id = id;
	}

	public WayPoint(BigDecimal longitude, BigDecimal latitude, Date date, Trip trip) {
		this(longitude, latitude, date);
		this.trip = trip;
	}
	
	public WayPoint(BigDecimal longitude, BigDecimal latitude, BigDecimal elevation) {
		this.longitude = longitude;
		this.latitude = latitude;
		this.elevation = elevation;
	}
	
	public WayPoint(long id, BigDecimal longitude, BigDecimal latitude, BigDecimal elevation) {
		this(longitude, latitude, elevation);
		this.id = id;
	}
	
	public WayPoint(BigDecimal longitude, BigDecimal latitude, Date date, BigDecimal elevation) {
		this(longitude, latitude, date);
		this.elevation = elevation;
	}
	
	public WayPoint(long id, BigDecimal longitude, BigDecimal latitude, Date date, BigDecimal elevation) {
		this(longitude, latitude, date, elevation);
		this.id = id;
	}
	
	public WayPoint(WayPoint point) {
		this(point.id,
			 point.longitude,
			 point.latitude,
			 point.date,
			 point.elevation);
	}
	
	/* **************************************************** */
	/*                    PUBLIC METHODS                    */
	/* **************************************************** */

	public String toString() {
		StringBuffer buffer = new StringBuffer();
		
		buffer.append("id=");
		buffer.append(this.getId());
		buffer.append(",longitude=");
		buffer.append(this.getLongitude());
		buffer.append(",latitude=");
		buffer.append(this.getLatitude());
		buffer.append(",date=");
		buffer.append(this.getDate());
		
		return buffer.toString();
	}
	
	public boolean equals(Object object) {
		boolean equals = false;
		
		if(object instanceof WayPoint) {
			WayPoint point = (WayPoint)object;
			equals = (this.getId() == point.getId()) &&
					 (this.getLatitude() == point.getLatitude()) &&
					 (this.getLongitude() == point.getLongitude()) &&
					 (this.getDate().equals(point.getDate()));
		}
		
		return equals;
	}
	
	/* **************************************************** */
	/*                  PROTECTED METHODS                   */
	/* **************************************************** */

	/* **************************************************** */
	/*                   PRIVATE METHODS                    */
	/* **************************************************** */

	/* **************************************************** */
	/*                  GETTERS AND SETTERS                 */
	/* **************************************************** */

	public long getId() {
		return this.id;
	}
	
	public void setId(long id) {
		this.id = id;
	}
	
	public Date getDate() {
		return this.date;
	}
	
	public void setDate(Date date) {
		this.date = date;
	}
	
	public BigDecimal getLatitude() {
		return this.latitude;
	}
	
	public void setLatitude(BigDecimal latitude) {
		this.latitude = latitude;
	}
	
	public BigDecimal getLongitude() {
		return this.longitude;
	}
	
	public void setLongitude(BigDecimal longitude) {
		this.longitude = longitude;
	}
	
	public Trip getTrip() {
		return trip;
	}

	public void setTrip(Trip trip) {
		this.trip = trip;
	}

	public BigDecimal getElevation() {
		return elevation;
	}

	public void setElevation(BigDecimal elevation) {
		this.elevation = elevation;
	}
	
	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}
}
